package com.example.vote.flow.service.impl;

import com.example.vote.flow.exception.ServiceException;
import com.example.vote.flow.mapper.VoteOptionMapper;
import com.example.vote.flow.mapper.VoteRecordMapper;
import com.example.vote.flow.mapper.VoteTopicMapper;
import com.example.vote.flow.pojo.core.Principle;
import com.example.vote.flow.pojo.entity.VoteOption;
import com.example.vote.flow.pojo.entity.VoteRecord;
import com.example.vote.flow.pojo.entity.VoteTopic;
import com.example.vote.flow.pojo.param.VoteRecordAddNewParam;
import com.example.vote.flow.pojo.vo.VoteOptionSimpleVO;
import com.example.vote.flow.pojo.vo.VoteTopicSimpleVO;
import com.example.vote.flow.service.IVoteRecordService;
import com.example.vote.flow.web.StateCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;

@Service
public class VoteRecordServiceImpl implements IVoteRecordService {

    @Autowired
    private VoteTopicMapper voteTopicMapper;
    @Autowired
    private VoteOptionMapper voteOptionMapper;
    @Autowired
    private VoteRecordMapper voteRecordMapper;

    @Override
    public void addNew(VoteRecordAddNewParam param, Principle principle, String ipAddress) {
        // 获取投票选项ID
        Long voteOptionId = param.getVoteOptionId();
        // 根据ID查询投票选项详情
        VoteOptionSimpleVO voteOption = voteOptionMapper.selectById(voteOptionId);
        // 检查投票选项是否存在
        if (voteOption == null) {
            throw new ServiceException(StateCode.ERROR_NOT_FOUND, "投票选项不存在");
        }

        // 获取投票主题ID
        Long voteTopicId = voteOption.getVoteTopicId();
        // 根据ID查询投票主题详情
        VoteTopicSimpleVO voteTopic = voteTopicMapper.selectById(voteTopicId);
        // 检查投票主题是否存在
        if (voteTopic == null) {
            throw new ServiceException(StateCode.ERROR_NOT_FOUND, "投票主题不存在");
        }
        // 检查投票是否尚未开启
        if (voteTopic.getStartTime().isAfter(LocalDateTime.now())) {
            throw new ServiceException(StateCode.ERROR_CONFLICT, "投票尚未开启");
        }
        // 检查投票是否已经结束
        if (voteTopic.getEndTime().isBefore(LocalDateTime.now())) {
            throw new ServiceException(StateCode.ERROR_CONFLICT, "投票已结束");
        }

        // 检查该IP地址的投票数是否达到上限
        int countByVoteTopicIdAndIpAddress = voteRecordMapper.countByVoteTopicIdAndIpAddress(voteTopicId, ipAddress);
        if (countByVoteTopicIdAndIpAddress >= voteTopic.getMaxVotesPerIp()) {
            throw new ServiceException(StateCode.ERROR_CONFLICT, "该IP已达到最大投票数");
        }

        // 检查该用户的投票数是否达到上限
        int countByVoteTopicIdAndUserId = voteRecordMapper.countByVoteTopicIdAndUserId(voteTopicId, principle.getId());
        if (countByVoteTopicIdAndUserId >= voteTopic.getMaxVotesPerUser()) {
            throw new ServiceException(StateCode.ERROR_CONFLICT, "该用户已达到最大投票数");
        }

        // 检查该用户今天是否已达到最大投票数
        int countByVoteTopicIdAndUserIdAndVoteDate
                = voteRecordMapper.countByVoteTopicIdAndUserIdAndVoteDate(
                voteTopicId, principle.getId(), LocalDate.now());
        if (countByVoteTopicIdAndUserIdAndVoteDate >= voteTopic.getMaxVotesPerUserPerDay()) {
            throw new ServiceException(StateCode.ERROR_CONFLICT, "该用户今天已达到最大投票数");
        }

        // 创建投票记录
        VoteRecord voteRecord = new VoteRecord();
        voteRecord.setUserId(principle.getId());
        voteRecord.setUsername(principle.getUsername());
        voteRecord.setVoteTopicId(voteTopicId);
        voteRecord.setVoteTopicTitle(voteTopic.getTitle());
        voteRecord.setVoteOptionId(voteOptionId);
        voteRecord.setVoteOptionContent(voteOption.getContent());
        voteRecord.setVoteTime(LocalDateTime.now());
        voteRecord.setIpAddress(ipAddress);
        voteRecordMapper.insert(voteRecord);

        // 更新投票选项数据中冗余存储的投票数
        VoteOption voteOptionForUpdate = new VoteOption();
        voteOptionForUpdate.setId(voteOptionId);
        voteOptionForUpdate.setRecordCount(voteOption.getRecordCount() + 1);
        voteOptionMapper.updateById(voteOptionForUpdate);

        // 更新投票主题数据中冗余存储的投票数
        VoteTopic voteTopicForUpdate = new VoteTopic();
        voteTopicForUpdate.setId(voteOption.getVoteTopicId());
        voteTopicForUpdate.setRecordCount(voteTopic.getRecordCount() + 1);
        voteTopicMapper.updateById(voteTopicForUpdate);
    }

}